#ifndef __InputStream_hpp__
#define __InputStream_hpp__

#include "Pointer.hpp"

namespace ge {

GE_DECLARE_CLASS( InputStream );

//----------------------------------------------------------------------------//
// InputStream
//----------------------------------------------------------------------------//

class InputStream : public virtual ReferenceCounted
{
 public:

     InputStream( const String& _name = 0, uint _size = 0 ) : m_name( _name ), m_size( 0 ), m_pos( 0 )
     {
     }

     uint Size( void ) const
     {
          return m_size;
     }

     const String& Name( void ) const
     {
          return m_name;
     }

     bool AtEnd( void ) const
     {
          return m_pos >= m_size;
     }

     uint GetPos( void ) const
     {
          return m_pos;
     }

     void SetPos( int _pos, bool _relative = false )
     {
          uint _old_pos = m_pos;

          if( _relative )
          {
               int64 _new_pos = m_pos + _pos;
               m_pos = (uint)geChoose( _new_pos < 0, 0, geChoose( _new_pos > m_size, m_size, _new_pos ) );
          }
          else
          {
               m_pos = (uint)geChoose( _pos < 0, 0, _pos );
          }

          if( _old_pos != m_pos ) _ApplyPos();
     }

     virtual uint Read( void* _dst, uint _size )
     {
          uint _readed = ReadFrom( m_pos, _dst, _size );
          m_pos += _readed;
          return _readed;
     }
     
     virtual uint ReadFrom( uint _offset, void* _dst, uint _size ) = 0;

 protected:

     virtual ~InputStream( void ) {}

     virtual void _ApplyPos( void ) {}

     String m_name;
     uint m_size;
     uint m_pos;
};

} // namespace ge

#endif//__InputStream_hpp__
